import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Polygon;
import java.util.Map;

import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.event.listeners.PaintListener;
import com.speljohan.rsbot.script.Calculations;
import com.speljohan.rsbot.script.Constants;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSCharacter;
import com.speljohan.rsbot.script.wrappers.RSInterface;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class GarrettsEssenceMiner extends Script implements PaintListener {

	// OTHER VARIABLES
	private long scriptStartTime = 0;
	private int runEnergy = random(50, 80);
	private int closest = -1;
	private int essCount = 0;
	private int runCount = 0;
	private int failCount = 0;
	private boolean runThis = true;
	private boolean setAltitude = true;
	private boolean runVar = true;
	private boolean checked = false;
	private String theAction = null;

	// OBJECT
	private RSObject door;
	private final int varrockBooth = 11402;
	private final int yanilleBooth = 2213;
	private final int closedDoor = 24381;
	private final int essence = 2491;
	private final int portal = 2492;

	// ITEM ID
	private final int[] pickaxe = { 1265, 1267, 1269, 1296, 1273, 1271, 1275 };
	private final int pureEssence = 7936;
	private final int runeEssence = 1436;

	// PATHS
	private final RSTile[] varrockPath = { new RSTile(3253, 3420),
			new RSTile(3258, 3410), new RSTile(3253, 3401) };
	private final RSTile[] yanillePath = { new RSTile(2612, 3092),
			new RSTile(2603, 3088), new RSTile(2600, 3088) };

	// TILES
	private final RSTile varrockTeleport = new RSTile(3253, 3401);
	private final RSTile varrockBank = new RSTile(3253, 3420);
	private final RSTile yanilleBank = new RSTile(2612, 3092);

	// NPC
	private final int Aubury = 553;
	private final int Distentor = 462;

	int mageGuildX[] = new int[] { 2590, 2593, 2597, 2597, 2597, 2593, 2586,
			2585, 2585, 2586, 2588 };
	int mageGuildY[] = new int[] { 3094, 3094, 3090, 3088, 3085, 3081, 3082,
			3087, 3088, 3090, 3092 };
	Polygon mageGuild = new Polygon(mageGuildX, mageGuildY, 11);

	// ENUM
	private static final int WALKTO = 1;
	private static final int OPENDOOR = 2;
	private static final int TELEPORT = 3;
	private static final int FINDPLACE = 4;
	private static final int MINE = 5;
	private static final int EXIT = 6;
	private static final int WALKBACK = 7;
	private static final int OPENBANK = 8;
	private static final int BANK = 9;
	private int ACTION = GarrettsEssenceMiner.WALKTO;

	public GarrettsEssenceMiner() {
		setParameter("author", "Garrett");
		setParameter("version", 1.04);
		setParameter("name", "Garrett's Essence Miner");
		setParameter("category", "Runecraft");
	}

	private int antiBan() {
		final int random = random(1, 24);

		switch (random) {
		case 1:
			final int x = random(0, 750);
			final int y = random(0, 500);
			if (random(1, 6) == 3) {
				moveMouse(0, 0, x, y);
			}
			return random(1000, 1500);

		case 2:
			if (getCurrentTab() != Constants.TAB_INVENTORY) {
				openTab(Constants.TAB_INVENTORY);
				return random(500, 750);
			} else {
				return random(500, 750);
			}

		case 3:
			if (random(1, 40) == 30) {
				if (getMyPlayer().isMoving()) {
					return random(750, 1000);
				}
				if (getCurrentTab() != Constants.TAB_STATS) {
					openTab(Constants.TAB_STATS);
				}
				moveMouse(665, 230, 40, 20);
				wait(random(3000, 6000));
				return random(100, 200);
			}

		case 4:
			if (random(1, 13) == 5) {
				int angle = getCameraAngle() + random(-90, 90);
				if (angle < 0) {
					angle = 0;
				}
				if (angle > 359) {
					angle = 0;
				}

				setCameraRotation(angle);
				return random(500, 750);
			}
		}
		return 500;
	}

	private boolean energyCheck() {
		try {
			if (gEnergy() >= runEnergy && !isRunning()) {
				runEnergy = random(35, 65);
				return true;
			} else {
				return false;
			}
		} catch (final Exception e) {
			return false;
		}
	}

	private boolean findLocation() {
		try {
			if (playerInArea(2934, 4822, 2921, 4810)) {
				// log("Player Location: South-East");
				closest = -1;
				return true;
			}
			if (playerInArea(2933, 4855, 2920, 4843)) {
				// log("Player Location: North-East");
				closest = -1;
				return true;
			}
			if (playerInArea(2899, 4858, 2880, 4840)) {
				// log("Player Location: North-West");
				closest = -1;
				return true;
			}
			if (playerInArea(2902, 4822, 2880, 4800)) {
				// log("Player Location: South-West");
				closest = -1;
				return true;
			}
			if (playerInArea(2920, 4841, 2900, 4820)) {
				// log("Player Location: Middle");
				int dist = 200;
				final RSTile[] loc = { new RSTile(2924, 4847),
						new RSTile(2926, 4819), new RSTile(2896, 4847),
						new RSTile(2897, 4817) };
				for (int i = 0; i < loc.length; i++) {
					if (distanceTo(loc[i]) < dist) {
						closest = i;
						dist = distanceTo(loc[i]);
					}
				}
				return true;
			}
			if (getNearestObjectByID(essence) != null) {
				closest = -1;
				return true;
			}
			return false;
		} catch (final Exception e) {
			return false;
		}
	}

	// *******************************************************//
	// OTHER METHODS
	// *******************************************************//

	private int gEnergy() {
		return Integer
				.parseInt(RSInterface.getChildInterface(750, 5).getText());
	}

	@Override
	public String getScriptDescription() {
		String html = "<html><head>";
		html += "</head><body>";
		html += "<center><strong><h2>" + getName() + " v" + getVersion()
				+ "</h2></strong></center>";
		html += "<center><strong>Start the script in Selected Bank with pickaxe equipped or in inventory.</strong></center>";
		html += "<br /><strong>What mining location?</strong><br />";
		html += "<select name='LOC'>";
		html += "<option>Varrock";
		html += "<option>Yanille</select>";
		html += "</body></html>";
		return html;
	}

	private boolean inAuburyShop() {
		try {
			if (playerInArea(3254, 3404, 3252, 3399)
					|| getMyPlayer().getLocation().getX() == 3255
					&& getMyPlayer().getLocation().getY() == 3401) {
				return true;
			}
			return false;
		} catch (final Exception e) {
			return false;
		}
	}

	public boolean inEquipment(final int... itemID) {
		try {
			for (final int item : itemID) {
				if (getEquipmentInterface().getInventoryItemCount(item) != 0) {
					return true;
				}
			}
		} catch (final Exception e) {
		}
		return false;
	}

	public boolean inInventory(final int... itemID) {
		try {
			for (final int i : itemID) {
				if (getInventoryCount(i) != 0) {
					return true;
				}
			}
		} catch (final Exception e) {
		}
		return false;
	}

	// *******************************************************//
	// MAIN LOOP
	// *******************************************************//
	@Override
	public int loop() {

		if (!isLoggedIn()) {
			wait(random(500, 1000));
			return random(50, 150);
		}

		if (setAltitude) {
			setCameraAltitude(true);
			wait(random(250, 500));
			setAltitude = false;
		}

		if (energyCheck()) {
			setRun(true);
			wait(random(750, 1000));
		}

		if (getPlane() == 1 && playerInArea(3257, 3423, 3250, 3416)) {
			if (onTile(new RSTile(3256, 3421), "Staircase", "Climb-down", 0.5,
					0.5, 0)) {
				wait(random(1500, 2000));
				while (getMyPlayer().isMoving()) {
					wait(100);
				}
				wait(random(1500, 2000));
			}
			return 100;
		}

		if (getPlane() == 1 && playerInArea(mageGuild)) {
			if (onTile(new RSTile(2590, 3091), "Staircase", "Climb-down", 0.2,
					0.5, 0)) {
				wait(random(1500, 2000));
				while (getMyPlayer().isMoving()) {
					wait(100);
				}
				wait(random(1500, 2000));
			}
			return 100;
		}

		if (distanceTo(new RSTile(2594, 9485)) <= 20) {
			if (onTile(new RSTile(2594, 9485), "Ladder", "Climb-up", 0.5, 0.5,
					random(20, 40))) {
				failCount = 0;
				while (!playerInArea(mageGuild)) {
					wait(50);
					failCount++;
					if (failCount > 40) {
						return 100;
					}
				}
				failCount = 0;
			}
			return 100;
		}

		if (!inEquipment(pickaxe) && !inInventory(pickaxe) && !checked) {
			log("Pickaxe was not found.");
			wait(10000);
			return 100;
		} else {
			checked = true;
		}

		antiBan();

		if (runVar) {
			runVarrock();
		} else {
			runYanille();
		}

		return random(50, 150);
	}

	public boolean onEssence(final RSTile tile, final String search,
			final String action) {
		if (!tile.isValid()) {
			return false;
		}
		if (distanceTo(tile) > 5) {
			walkTileMM(tile);
			wait(random(340, 1310));
		}

		try {
			Point screenLoc = null;
			for (int i = 0; i < 30; i++) {
				screenLoc = Calculations.tileToScreen(tile, 1, 1, 40);
				if (!pointOnScreen(screenLoc)) {
					return false;
				}
				if (getMenuItems().get(0).toLowerCase().contains(
						search.toLowerCase())) {
					break;
				}
				if (getMouseLocation().equals(screenLoc)) {
					break;
				}
				moveMouse(screenLoc);
			}
			screenLoc = Calculations.tileToScreen(tile);
			if (getMenuItems().size() <= 1) {
				return false;
			}
			if (getMenuItems().get(0).toLowerCase().contains(
					action.toLowerCase())) {
				clickMouse(true);
				return true;
			} else {
				clickMouse(false);
				return atMenu(action);
			}
		} catch (final Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	// *******************************************************//
	// ON FINISH
	// *******************************************************//
	@Override
	public void onFinish() {
		Bot.getEventManager().removeListener(PaintListener.class, this);
	}

	public boolean onNPC(final RSCharacter npc, final String npcName,
			final String action) {
		if (npc == null) {
			return false;
		}
		final RSTile tile = npc.getLocation();
		if (!tile.isValid()) {
			return false;
		}

		final Point checkScreen = npc.getScreenLocation();
		if (!pointOnScreen(checkScreen)) {
			walkTileMM(tile);
			wait(random(340, 700));
		}

		try {
			Point screenLoc = null;
			for (int i = 0; i < 30; i++) {
				screenLoc = npc.getScreenLocation();
				if (!npc.isValid() || !pointOnScreen(screenLoc)) {
					return false;
				}
				if (getMenuItems().get(0).toLowerCase().contains(
						npcName.toLowerCase())) {
					break;
				}
				if (getMouseLocation().equals(screenLoc)) {
					break;
				}
				moveMouse(screenLoc);
			}
			screenLoc = npc.getScreenLocation();
			if (getMenuItems().size() <= 1) {
				return false;
			}
			if (getMenuItems().get(0).toLowerCase().contains(
					action.toLowerCase())) {
				clickMouse(true);
				return true;
			} else {
				clickMouse(false);
				return atMenu(action);
			}
		} catch (final Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	// *******************************************************//
	// PAINT SCREEN
	// *******************************************************//
	public void onRepaint(final Graphics g) {
		long runTime = 0;
		long seconds = 0;
		long minutes = 0;
		long hours = 0;

		runTime = System.currentTimeMillis() - scriptStartTime;
		seconds = runTime / 1000;
		if (seconds >= 60) {
			minutes = seconds / 60;
			seconds -= minutes * 60;
		}
		if (minutes >= 60) {
			hours = minutes / 60;
			minutes -= hours * 60;
		}

		if (getCurrentTab() == Constants.TAB_INVENTORY) {
			g.setColor(new Color(0, 0, 0, 175));
			g.fillRoundRect(555, 210, 175, 250, 10, 10);
			g.setColor(Color.WHITE);
			final int[] coords = new int[] { 225, 240, 255, 270, 285, 300, 315,
					330, 345, 360, 375, 390, 405, 420, 435, 450 };
			g.drawString(getName(), 561, coords[0]);
			g.drawString("Version: " + getVersion(), 561, coords[1]);
			g.drawString("Run Time: " + hours + ":" + minutes + ":" + seconds,
					561, coords[3]);
			g.drawString("Run Time: " + hours + ":" + minutes + ":" + seconds,
					561, coords[3]);
			g.drawString("Total Runs: " + runCount, 561, coords[5]);
			g.drawString("Total Essence: " + essCount, 561, coords[6]);
			g.drawString("Action: " + theAction, 561, coords[15]);
		}
	}

	// *******************************************************//
	// ON START
	// *******************************************************//
	@Override
	public boolean onStart(final Map<String, String> args) {
		scriptStartTime = System.currentTimeMillis();
		final String LOC = args.get("LOC");
		if (LOC.equals("Varrock")) {
			runVar = true;
		} else {
			runVar = false;
		}
		return true;
	}

	private boolean onTile(final RSTile tile, final String search,
			final String action, final double dx, final double dy,
			final int height) {
		if (!tile.isValid()) {
			return false;
		}

		Point checkScreen = null;
		checkScreen = Calculations.tileToScreen(tile, dx, dy, height);
		if (!pointOnScreen(checkScreen)) {
			walkTileMM(tile.randomizeTile(1, 1));
			wait(random(340, 1310));
		}

		try {
			Point screenLoc = null;
			for (int i = 0; i < 30; i++) {
				screenLoc = Calculations.tileToScreen(tile, dx, dy, height);
				if (!pointOnScreen(screenLoc)) {
					return false;
				}
				if (getMenuItems().get(0).toLowerCase().contains(
						search.toLowerCase())) {
					break;
				}
				if (getMouseLocation().equals(screenLoc)) {
					break;
				}
				moveMouse(screenLoc);
			}
			screenLoc = Calculations.tileToScreen(tile, dx, dy, height);
			if (getMenuItems().get(0).toLowerCase().contains(
					action.toLowerCase())) {
				clickMouse(true);
				return true;
			} else {
				clickMouse(false);
				return atMenu(action);
			}
		} catch (final Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	public boolean onYanilleBank(final RSTile tile, final String search,
			final String action) {
		if (!tile.isValid()) {
			return false;
		}

		final Point checkScreen = Calculations.tileToScreen(tile);
		if (!pointOnScreen(checkScreen)) {
			if (getMyPlayer().isMoving()) {
				return false;
			}
			walkTileMM(new RSTile(tile.getX() - random(3, 5), tile.getY()));
			return false;
		}

		try {
			Point screenLoc = null;
			for (int i = 0; i < 30; i++) {
				screenLoc = Calculations.tileToScreen(tile);
				if (!pointOnScreen(screenLoc)) {
					return false;
				}
				if (getMenuItems().get(0).toLowerCase().contains(
						search.toLowerCase())) {
					break;
				}
				if (getMouseLocation().equals(screenLoc)) {
					break;
				}
				moveMouse(screenLoc);
			}
			screenLoc = Calculations.tileToScreen(tile);
			if (getMenuItems().size() <= 1) {
				return false;
			}
			if (getMenuItems().get(0).toLowerCase().contains(
					action.toLowerCase())) {
				clickMouse(true);
				return true;
			} else {
				clickMouse(false);
				return atMenu(action);
			}
		} catch (final Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	private boolean playerInArea(final int maxX, final int maxY,
			final int minX, final int minY) {
		final int x = getMyPlayer().getLocation().getX();
		final int y = getMyPlayer().getLocation().getY();
		if (x >= minX && x <= maxX && y >= minY && y <= maxY) {
			return true;
		}
		return false;
	}

	public boolean playerInArea(final Polygon area) {
		return area.contains(new Point(getMyPlayer().getLocation().getX(),
				getMyPlayer().getLocation().getY()));
	}

	private void runVarrock() {
		if (ACTION == GarrettsEssenceMiner.WALKTO) {
			theAction = "Walk to Aubury";
			try {
				if (getInventoryCount(pureEssence, runeEssence) > 0) {
					ACTION = GarrettsEssenceMiner.WALKBACK;
				}
			} catch (final Exception e) {
			}
			try {
				if (distanceTo(varrockTeleport) > 7) {
					walkPath(varrockPath, false);
					return;
				} else {
					ACTION = GarrettsEssenceMiner.OPENDOOR;
					return;
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.OPENDOOR) {
			theAction = "Checking Door";
			try {
				if (getNearestObjectByID(portal) != null) {
					ACTION = GarrettsEssenceMiner.EXIT;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				if (inAuburyShop() && !isInventoryFull()) {
					ACTION = GarrettsEssenceMiner.TELEPORT;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				door = getObjectAt(3253, 3398);
				if (door != null) {
					if (door.getID() == closedDoor) {
						if (getCameraAngle() >= 0 && getCameraAngle() <= 10
								|| getCameraAngle() >= 350
								&& getCameraAngle() <= 360) {
							if (atDoor(door, "North", "Open")) {
								failCount = 0;
								while (getObjectAt(3253, 3398).getID() == closedDoor) {
									wait(50);
									failCount++;
									if (getMyPlayer().isMoving()) {
										failCount = 0;
									}
									if (failCount > 30) {
										return;
									}
								}
								failCount = 0;
								return;
							}
						} else {
							final int a = random(1, 3);
							if (a == 1) {
								setCameraRotation(random(350, 360));
							} else {
								setCameraRotation(random(0, 10));
							}
							return;
						}
					} else {
						if (isInventoryFull()) {
							ACTION = GarrettsEssenceMiner.WALKBACK;
							return;
						} else {
							ACTION = GarrettsEssenceMiner.TELEPORT;
							return;
						}
					}
				} else {
					if (isInventoryFull()) {
						ACTION = GarrettsEssenceMiner.WALKBACK;
						return;
					} else {
						ACTION = GarrettsEssenceMiner.TELEPORT;
						return;
					}
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.TELEPORT) {
			theAction = "Teleporting";
			try {
				if (getNearestNPCByID(Aubury) == null
						|| playerInArea(2950, 4870, 2870, 4790)) {
					ACTION = GarrettsEssenceMiner.FINDPLACE;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				door = getObjectAt(3253, 3398);
				if (door != null) {
					if (door.getID() == closedDoor && !inAuburyShop()) {
						ACTION = GarrettsEssenceMiner.OPENDOOR;
						return;
					}
				}
			} catch (final Exception e) {
			}
			try {
				if (onNPC(getNearestNPCByID(Aubury), "Aubury", "Teleport")) {
					failCount = 0;
					while (getNearestNPCByID(Aubury) != null) {
						wait(50);
						failCount++;
						if (getMyPlayer().isMoving()) {
							failCount = 0;
						}
						if (failCount > 30) {
							return;
						}
					}
					failCount = 0;
					return;
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.FINDPLACE) {
			theAction = "Finding Location";
			try {
				if (!playerInArea(2950, 4870, 2870, 4790)) {
					ACTION = GarrettsEssenceMiner.TELEPORT;
					return;
				}
				if (runThis) {
					if (findLocation()) {
						runThis = false;
					}
				}
				if (!runThis) {
					if (closest != -1) {
						if (closest == 0) {
							walkTileMM(new RSTile(2919, 4840));
							closest = -1;
							return;
						} else if (closest == 1) {
							walkTileMM(new RSTile(2919, 4823));
							closest = -1;
							return;
						} else if (closest == 2) {
							walkTileMM(new RSTile(2902, 4842));
							closest = -1;
							return;
						} else if (closest == 3) {
							walkTileMM(new RSTile(2902, 4821));
							closest = -1;
							return;
						} else {
							closest = -1;
							return;
						}
					} else {
						closest = -1;
						runThis = true;
						ACTION = GarrettsEssenceMiner.MINE;
						return;
					}
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.MINE) {
			theAction = "Mining";
			try {
				if (!playerInArea(2950, 4870, 2870, 4790)) {
					ACTION = GarrettsEssenceMiner.TELEPORT;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				if (isInventoryFull()) {
					ACTION = GarrettsEssenceMiner.EXIT;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				if (getMyPlayer().getAnimation() == -1) {
					wait(random(500, 1000));
					if (getMyPlayer().getAnimation() != -1) {
						return;
					}
					if (onEssence(getNearestObjectByID(essence).getLocation(),
							"Essence", "Mine")) {
						wait(random(750, 1000));
						while (getMyPlayer().isMoving()) {
							wait(100);
						}
						wait(random(750, 1000));
						return;
					}
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.EXIT) {
			theAction = "Leaving";
			try {
				if (getNearestNPCByID(Aubury) != null) {
					ACTION = GarrettsEssenceMiner.OPENDOOR;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				if (onTile(getNearestObjectByID(portal).getLocation(),
						"Portal", "Use", 0.5, 0.5, 0)) {
					failCount = 0;
					while (getNearestNPCByID(Aubury) == null) {
						wait(50);
						failCount++;
						if (getMyPlayer().isMoving()) {
							failCount = 0;
						}
						if (failCount > 30) {
							return;
						}
					}
					failCount = 0;
					return;
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.WALKBACK) {
			theAction = "Walking to bank";
			try {
				if (getNearestObjectByID(portal) != null) {
					ACTION = GarrettsEssenceMiner.EXIT;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				if (distanceTo(varrockBank) > 5) {
					walkPath(varrockPath, true);
					return;
				} else {
					ACTION = GarrettsEssenceMiner.OPENBANK;
					return;
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.OPENBANK) {
			theAction = "Opening bank";
			try {
				if (bank.isOpen()) {
					ACTION = GarrettsEssenceMiner.BANK;
					essCount += getInventoryCount(pureEssence, runeEssence);
					runCount += 1;
					return;
				}
				if (onTile(getNearestObjectByID(varrockBooth).getLocation(),
						"Bank booth", "Use-quickly", 0.5, 0.5, 0)) {
					failCount = 0;
					while (!bank.isOpen()) {
						wait(50);
						failCount++;
						if (getMyPlayer().isMoving()) {
							failCount = 0;
						}
						if (failCount > 30) {
							return;
						}
					}
					failCount = 0;
					return;
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.BANK) {
			theAction = "Banking";
			try {
				if (getInventoryCount() <= 1) {
					ACTION = GarrettsEssenceMiner.WALKTO;
					return;
				}
				if (bank.isOpen()) {
					if (inInventory(pickaxe)) {
						bank.depositAllExcept(pickaxe);
						wait(random(250, 500));
					} else {
						bank.depositAll();
						wait(random(250, 500));
					}
				} else {
					wait(random(500, 1000));
					if (!bank.isOpen() && !getMyPlayer().isMoving()) {
						if (onTile(getNearestObjectByID(varrockBooth)
								.getLocation(), "Bank booth", "Use-quickly",
								0.5, 0.5, 0)) {
							failCount = 0;
							while (!bank.isOpen()) {
								wait(50);
								failCount++;
								if (getMyPlayer().isMoving()) {
									failCount = 0;
								}
								if (failCount > 30) {
									return;
								}
							}
							failCount = 0;
							return;
						}
					}
				}
			} catch (final Exception e) {
			}
		}
	}

	private void runYanille() {
		if (ACTION == GarrettsEssenceMiner.WALKTO) {
			theAction = "Walk to Distentor";
			try {
				if (playerInArea(mageGuild)) {
					ACTION = GarrettsEssenceMiner.TELEPORT;
				}
			} catch (final Exception e) {
			}
			try {
				if (getInventoryCount(pureEssence, runeEssence) > 0) {
					ACTION = GarrettsEssenceMiner.WALKBACK;
				}
			} catch (final Exception e) {
			}
			try {
				if (distanceTo(new RSTile(2597, 3088)) > 6) {
					walkPath(yanillePath, false);
					return;
				} else {
					ACTION = GarrettsEssenceMiner.OPENDOOR;
					return;
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.OPENDOOR) {
			theAction = "Opening Door";
			try {
				double randD = 0;
				final int rando = random(1, 3);
				if (rando == 1) {
					randD = 0.0;
				} else {
					randD = 0.1;
				}
				if (playerInArea(mageGuild)) {
					if (onTile(new RSTile(2597, 3088), "door", "Open", randD,
							0.5, 50)) {
						int countFail = 0;
						while (playerInArea(mageGuild)) {
							wait(50);
							countFail++;
							if (getMyPlayer().isMoving()) {
								failCount = 0;
							}
							if (countFail > 75) {
								return;
							}
						}
						countFail = 0;
						ACTION = GarrettsEssenceMiner.WALKBACK;
						return;
					}
				} else {
					if (onTile(new RSTile(2597, 3088), "door", "Open", randD,
							0.5, 50)) {
						int countFail = 0;
						while (!playerInArea(mageGuild)) {
							wait(50);
							countFail++;
							if (getMyPlayer().isMoving()) {
								failCount = 0;
							}
							if (countFail > 75) {
								return;
							}
						}
						countFail = 0;
						ACTION = GarrettsEssenceMiner.TELEPORT;
						return;
					}
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.TELEPORT) {
			theAction = "Teleporting";
			try {
				if (getNearestNPCByID(Distentor) == null
						|| playerInArea(2950, 4870, 2870, 4790)) {
					ACTION = GarrettsEssenceMiner.FINDPLACE;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				if (!playerInArea(mageGuild)) {
					ACTION = GarrettsEssenceMiner.OPENDOOR;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				if (onNPC(getNearestNPCByID(Distentor), "Distentor", "Teleport")) {
					failCount = 0;
					while (playerInArea(mageGuild)) {
						wait(50);
						failCount++;
						if (getMyPlayer().isMoving()) {
							failCount = 0;
						}
						if (failCount > 35) {
							return;
						}
					}
					failCount = 0;
					return;
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.FINDPLACE) {
			theAction = "Finding Location";
			try {
				if (!playerInArea(2950, 4870, 2870, 4790)) {
					ACTION = GarrettsEssenceMiner.TELEPORT;
					return;
				}
				if (runThis) {
					if (findLocation()) {
						runThis = false;
					}
				}
				if (!runThis) {
					if (closest != -1) {
						if (closest == 0) {
							walkTileMM(new RSTile(2919, 4840));
							closest = -1;
							return;
						} else if (closest == 1) {
							walkTileMM(new RSTile(2919, 4823));
							closest = -1;
							return;
						} else if (closest == 2) {
							walkTileMM(new RSTile(2902, 4842));
							closest = -1;
							return;
						} else if (closest == 3) {
							walkTileMM(new RSTile(2902, 4821));
							closest = -1;
							return;
						} else {
							closest = -1;
							return;
						}
					} else {
						closest = -1;
						runThis = true;
						ACTION = GarrettsEssenceMiner.MINE;
						return;
					}
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.MINE) {
			theAction = "Mining";
			try {
				if (!playerInArea(2950, 4870, 2870, 4790)) {
					ACTION = GarrettsEssenceMiner.TELEPORT;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				if (isInventoryFull()) {
					ACTION = GarrettsEssenceMiner.EXIT;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				if (getMyPlayer().getAnimation() == -1) {
					wait(random(500, 1000));
					if (getMyPlayer().getAnimation() != -1) {
						return;
					}
					if (onEssence(getNearestObjectByID(essence).getLocation(),
							"Essence", "Mine")) {
						wait(random(750, 1000));
						while (getMyPlayer().isMoving()) {
							wait(100);
						}
						wait(random(750, 1000));
						return;
					}
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.EXIT) {
			theAction = "Leaving";
			try {
				if (getNearestNPCByID(Distentor) != null
						&& playerInArea(mageGuild)) {
					ACTION = GarrettsEssenceMiner.OPENDOOR;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				if (onTile(getNearestObjectByID(portal).getLocation(),
						"Portal", "Use", 0.5, 0.5, 0)) {
					failCount = 0;
					while (!playerInArea(mageGuild)) {
						wait(50);
						failCount++;
						if (getMyPlayer().isMoving()) {
							failCount = 0;
						}
						if (failCount > 35) {
							return;
						}
					}
					failCount = 0;
					return;
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.WALKBACK) {
			theAction = "Walking to bank";
			try {
				if (getNearestObjectByID(portal) != null) {
					ACTION = GarrettsEssenceMiner.EXIT;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				if (playerInArea(mageGuild)) {
					ACTION = GarrettsEssenceMiner.OPENDOOR;
					return;
				}
			} catch (final Exception e) {
			}
			try {
				if (distanceTo(yanilleBank) > 5) {
					walkPath(yanillePath, true);
					return;
				} else {
					ACTION = GarrettsEssenceMiner.OPENBANK;
					return;
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.OPENBANK) {
			theAction = "Opening bank";
			try {
				if (bank.isOpen()) {
					ACTION = GarrettsEssenceMiner.BANK;
					essCount += getInventoryCount(pureEssence, runeEssence);
					runCount += 1;
					return;
				}
				if (onYanilleBank(getNearestObjectByID(yanilleBooth)
						.getLocation(), "Bank booth", "Use-quickly")) {
					failCount = 0;
					while (!bank.isOpen()) {
						wait(50);
						failCount++;
						if (getMyPlayer().isMoving()) {
							failCount = 0;
						}
						if (failCount > 30) {
							return;
						}
					}
					failCount = 0;
					return;
				}
			} catch (final Exception e) {
			}
		}
		if (ACTION == GarrettsEssenceMiner.BANK) {
			theAction = "Banking";
			try {
				if (getInventoryCount() <= 1) {
					ACTION = GarrettsEssenceMiner.WALKTO;
					return;
				}
				if (bank.isOpen()) {
					if (inInventory(pickaxe)) {
						bank.depositAllExcept(pickaxe);
						wait(random(250, 500));
					} else {
						bank.depositAll();
						wait(random(250, 500));
					}
				} else {
					wait(random(500, 1000));
					if (!bank.isOpen() && !getMyPlayer().isMoving()) {
						if (onYanilleBank(getNearestObjectByID(yanilleBooth)
								.getLocation(), "Bank booth", "Use-quickly")) {
							failCount = 0;
							while (!bank.isOpen()) {
								wait(50);
								failCount++;
								if (getMyPlayer().isMoving()) {
									failCount = 0;
								}
								if (failCount > 30) {
									return;
								}
							}
							failCount = 0;
							return;
						}
					}
				}
			} catch (final Exception e) {
			}
		}
	}

	private void walkPath(final RSTile[] path, final boolean reverse) {
		if (!reverse) {
			if (!getMyPlayer().isMoving()
					|| distanceTo(getDestination()) <= random(4, 7)) {
				walkPathMM(randomizePath(path, 2, 2), 17);
				return;
			} else {
				antiBan();
			}
		} else {
			if (!getMyPlayer().isMoving()
					|| distanceTo(getDestination()) <= random(4, 7)) {
				walkPathMM(randomizePath(reversePath(path), 2, 2), 17);
				return;
			} else {
				antiBan();
			}
		}
	}
}